home *** CD-ROM | disk | FTP | other *** search
- /*
- file PackageWindow.c
-
- Description:
- This file contains the routines that implement the functionality
- provided by the main window displayed by the PackageTool
- application.
-
- PackageTool is an application illustrating how to create application
- packages in Mac OS 9. It provides a simple interface for converting
- correctly formatted folders into packages and vice versa.
-
- by John Montbriand, 1999.
-
- Copyright: © 1999 by Apple Computer, Inc.
- all rights reserved.
-
- Disclaimer:
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
-
- Change History (most recent first):
- 10/19/99 created by John Montbriand
- */
-
- #include "PackageWindow.h"
- #include "PackageTool.h"
- #include "PackageUtils.h"
- #include "Utilities.h"
- #include <Drag.h>
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Appearance.h>
- #include <Icons.h>
- #include <string.h>
- #include <TextUtils.h>
-
-
-
-
-
- enum { /* picture displayed when selection is empty */
- kSpashPictResource = 128
- };
-
- /* main window dialog constants */
- enum {
- kPackageDialogResource = 128,
- kPackageUserItem = 1,
- kFolderItem = 2,
- kPackageItem = 3,
- /* kFolderIsPackage and kFolderIsFolder are used for
- internal tracking of the state of the kFolderItem and
- the kPackageItem dialog controls. */
- kFolderIsPackage = 100, /* item being displayed is a package */
- kFolderIsFolder = 101 /* item being displayed is a folder */
- };
-
-
- /* variables used to record properties of the main window */
- DialogPtr gPackageWindow = NULL; /* a pointer to the main dialog */
- PicHandle gSplashPict; /* splash image displayed in gIconBox when there is no file selected */
- Rect gIconBox; /* area in the window where the information about the current file is drawn */
- Rect gIconImage; /* area inside of gIconBox where the icon is drawn */
- ControlHandle gPackageButton; /* control for setting gFolderTypeSelection to kFolderIsPackage */
- ControlHandle gFolderButton; /* control for setting gFolderTypeSelection to kFolderIsFolder */
-
- /* variables used to record information about the file being displayed */
- Boolean gFileInDisplay = false; /* true when gFileAlias contains an alias handle */
- AliasHandle gFileAlias = NULL; /* an alias to the last file dragged into the gIconBox */
- IconRef gIconRef = NULL; /* an icon services reference to an icon for the file */
- short gFolderTypeSelection = kFolderIsFolder; /* determines the type of data we will provide for drags */
- Boolean gPWActive = false;
-
- /* these routines are used both in the receive handler and inside of the
- tracking handler. The following variables are shared between MyDragTrackingHandler
- and MyDragReceiveHandler. */
- static Boolean gApprovedDrag = false; /* set to true if the drag is approved */
- static Boolean gInIconBox = false; /* set true if the drag is inside our drop box */
-
- /* procedure pointers used in the main window */
- DragReceiveHandlerUPP gMainReceiveHandler = NULL; /* receive handler for the main dialog */
- DragTrackingHandlerUPP gMainTrackingHandler = NULL; /* tracking handler for the main dialog */
- UserItemUPP myUserItem; /* UPP for the icon's user item. This routine draws into gIconBox */
-
-
- Boolean IsPackageWindow(WindowPtr target) {
- return (target == gPackageWindow);
- }
-
-
- /* ApproveDragReference is called by the drag tracking handler to determine
- if the contents of the drag can be handled by our receive handler.
- here, we only allow packages and folders. */
- static pascal OSErr ApproveDragReference(DragReference theDragRef, Boolean *approved) {
- OSErr err;
- UInt16 itemCount;
- DragAttributes dragAttrs;
- ItemReference theItem;
- HFSFlavor targetFile;
- long theSize;
-
- /* we cannot drag to our own window */
- if ((err = GetDragAttributes(theDragRef, &dragAttrs)) != noErr) goto bail;
- if ((dragAttrs & kDragInsideSenderWindow) != 0) { err = userCanceledErr; goto bail; }
-
- /* we only accept drags containing one item */
- if ((err = CountDragItems(theDragRef, &itemCount)) != noErr) goto bail;
- if (itemCount != 1) { err = paramErr; goto bail; }
-
- /* gather information about the drag & a reference to item one. */
- if ((err = GetDragItemReferenceNumber(theDragRef, 1, &theItem)) != noErr) goto bail;
-
- /* try to get a HFSFlavor*/
- theSize = sizeof(HFSFlavor);
- err = GetFlavorData(theDragRef, theItem, flavorTypeHFS, &targetFile, &theSize, 0);
- if (err != noErr) goto bail;
-
- /* it must be a folder or a package */
- if (IdentifyPackage(&targetFile.fileSpec, NULL))
- *approved = true;
- else if (targetFile.fileCreator == 'MACS' && targetFile.fileType == 'fold')
- *approved = true;
- else {
- err = paramErr;
- goto bail;
- }
-
- return noErr;
- bail:
- /* an error occured, clean up. set result to false. */
- *approved = false;
- return err;
- }
-
-
-
-
- /* MyDragTrackingHandler is called for tracking the mouse while a drag is passing over our
- window. if the drag is approved, then the drop box will be hilitied appropriately
- as the mouse passes over it. */
- static pascal OSErr MyDragTrackingHandler(DragTrackingMessage message, WindowPtr theWindow, void *refCon, DragReference theDragRef) {
- /* we're drawing into the image well if we hilite... */
- switch (message) {
-
- case kDragTrackingEnterWindow:
- { Point mouse;
- gApprovedDrag = false;
- if (theWindow == FrontWindow()) {
- if (ApproveDragReference(theDragRef, &gApprovedDrag) != noErr) break;
- if ( ! gApprovedDrag ) break;
- SetPort(theWindow);
- GetMouse(&mouse);
- if (PtInRect(mouse, &gIconBox)) { /* if we're in the box, hilite... */
- SetPort(theWindow);
- gInIconBox = (ShowDragHiliteBox(theDragRef, &gIconBox) == noErr);
- }
- }
- }
- break;
-
- case kDragTrackingInWindow:
- if (gApprovedDrag) {
- Point mouse;
- SetPort(theWindow);
- GetMouse(&mouse);
- if (PtInRect(mouse, &gIconBox)) {
- if ( ! gInIconBox) { /* if we're entering the box, hilite... */
- SetPort(theWindow);
- gInIconBox = (ShowDragHiliteBox(theDragRef, &gIconBox) == noErr);
- }
- } else if (gInIconBox) { /* if we're exiting the box, unhilite... */
- HideDragHilite(theDragRef);
- gInIconBox = false;
- }
- }
- break;
-
- case kDragTrackingLeaveWindow:
- if (gApprovedDrag && gInIconBox) {
- HideDragHilite(theDragRef);
- }
- gApprovedDrag = gInIconBox = false;
- break;
- }
- return noErr; // there's no point in confusing Drag Manager or its caller
- }
-
-
-
-
-
-
- /* MyDragReceiveHandler receives drags that are dropped into the
- main window. here, we only receive packages or folders. */
- static pascal OSErr MyDragReceiveHandler(WindowPtr theWindow, void *refcon, DragReference theDragRef) {
- ItemReference theItem;
- HFSFlavor targetFile;
- Size theSize;
- OSErr err;
-
- /* validate the drag. Recall the receive handler will only be called after
- the tracking handler has received a kDragTrackingInWindow event. As a result,
- the gApprovedDrag and gInIconBox will be defined when we arrive here. Hence,
- there is no need to spend extra time validating the drag at this point. */
- if ( ! (gApprovedDrag && gInIconBox) ) { err = userCanceledErr; goto bail; }
-
- /* get the first item reference */
- err = GetDragItemReferenceNumber(theDragRef, 1, &theItem);
- if (err != noErr) goto bail;
-
- /* try to get a HFSFlavor*/
- theSize = sizeof(HFSFlavor);
- err = GetFlavorData(theDragRef, theItem, flavorTypeHFS, &targetFile, &theSize, 0);
- if (err != noErr) goto bail;
-
- /* display the located file*/
- SetNewDisplay(&targetFile.fileSpec);
- return noErr;
- bail:
- return err;
- }
-
-
-
-
- /* SetNewDisplay is called to set the file or folder being displayed in the main window.
- Here, structures are deallocated and an alias is saved referring to the file.
- SetNewDisplay is called from the drag receive handler and since it is not
- safe to call "GetIconSuiteFromFinder()" from inside of the drag receive handler
- (it uses apple events), the flag is used to defer that operation
- until the next time ValidateFDPWindowDisplay. ValidateFDPWindowDisplay is
- called from the main loop. If targetFile is NULL, then the display is cleared. */
- void SetNewDisplay(FSSpec *targetFile) {
- SInt16 theLabel;
- FSSpec mainPackageFile;
- /* remove the old file */
- if (gFileInDisplay) {
- DisposeHandle((Handle) gFileAlias);
- gFileAlias = NULL;
- ReleaseIconRef(gIconRef);
- gIconRef = NULL;
- gFileInDisplay = false;
- SetPort(gPackageWindow);
- InvalRect(&gIconBox);
- }
- /* if there's no new file, we're done */
- if (targetFile == NULL) goto bail;
- /* create the new alias */
- if (NewAliasMinimal(targetFile, &gFileAlias) != noErr) goto bail;
- /* determine the kind of object we're displaying */
- if (IdentifyPackage(targetFile, &mainPackageFile)) {
- if (GetIconRefFromFile(&mainPackageFile, &gIconRef, &theLabel) != noErr) goto bail;
- gFolderTypeSelection = kFolderIsPackage;
- } else {
- if (GetIconRefFromFile(targetFile, &gIconRef, &theLabel) != noErr) goto bail;
- gFolderTypeSelection = kFolderIsFolder;
- }
- /* set up the controls */
- SetControlValue(gPackageButton, (gFolderTypeSelection == kFolderIsPackage ? 1 : 0));
- SetControlValue(gFolderButton, (gFolderTypeSelection == kFolderIsFolder ? 1 : 0));
- HiliteControl(gPackageButton, (gPWActive ? 0 : 255));
- HiliteControl(gFolderButton, (gPWActive ? 0 : 255));
- /* update the window */
- SetPort(gPackageWindow);
- InvalRect(&gIconBox);
- /* set the flag and return */
- gFileInDisplay = true;
- return;
- bail:
- if (gFileAlias != NULL) DisposeHandle((Handle) gFileAlias);
- if (gIconRef != NULL) ReleaseIconRef(gIconRef);
- HiliteControl(gPackageButton, 255);
- HiliteControl(gFolderButton, 255);
- SetPort(gPackageWindow);
- InvalRect(&gIconBox);
- gFileInDisplay = false;
- }
-
-
-
-
- /* ActivatePackageWindow handles an activate event for the
- package window. */
- void ActivatePackageWindow(WindowPtr target, Boolean activate) {
- HiliteControl(gPackageButton, ((gPackageWindow == FrontWindow() && gFileInDisplay) ? 0 : 255));
- HiliteControl(gFolderButton, ((gPackageWindow == FrontWindow() && gFileInDisplay) ? 0 : 255));
- DrawDialog(gPackageWindow);
- gPWActive = activate;
- }
-
-
-
- /* PackageWindowUserItem draws the image in the drop box in the window. If the window
- is not the active window, then the image is drawn grayed out. If appearance
- is in use, then the drop box is drawn as a generic well. */
- static pascal void PackageWindowUserItem(WindowPtr theWindow, DialogItemIndex itemNo) {
- RGBColor sForground, sBackground;
- RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF}, rgbBlack = {0, 0, 0}, rgbGray = {0x7FFF, 0x7FFF, 0x7FFF};
- FSSpec target;
- ThemeDrawState themeDrawState;
- Boolean wasChanged;
- /* set up */
- SetPort(theWindow);
- /* set the colors we're using for drawing */
- GetForeColor(&sForground);
- GetBackColor(&sBackground);
- RGBForeColor(&rgbBlack);
- RGBBackColor(&rgbWhite);
- /* draw the frame */
- themeDrawState = (gPWActive && (theWindow == FrontWindow())) ? kThemeStateActive : kThemeStateInactive;
- DrawThemeGenericWell(&gIconBox, themeDrawState, true);
- /* verify that we still have a file */
- if (ResolveAlias(NULL, gFileAlias, &target, &wasChanged) != noErr) {
- DisposeHandle((Handle) gFileAlias);
- gFileAlias = NULL;
- ReleaseIconRef(gIconRef);
- gIconRef = NULL;
- gFileInDisplay = false;
- }
- /* draw the file information */
- if (gFileInDisplay) {
- OSErr err;
- short baseLine;
- FontInfo fin;
- Str255 name;
- /* begin drawing */
- TextFont(kFontIDGeneva); /* geneva */
- TextSize(9);
- GetFontInfo(&fin);
- /* draw the icon image */
- err = PlotIconRef(&gIconImage, kAlignNone, kTransformNone, kIconServicesNormalUsageFlag, gIconRef);
- /* draw the file name */
- baseLine = gIconImage.bottom + fin.ascent;
- memcpy(name, target.name, target.name[0] + 1);
- TruncString(gIconBox.right - gIconBox.left - 4, name, truncEnd);
- MoveTo((gIconBox.left + gIconBox.right - StringWidth(name))/2, baseLine);
- DrawString(name);
- /* end drawing */
- TextFont(systemFont); /* back to the system font */
- TextSize(12);
- } else {
- Rect rPic;
- rPic = (**gSplashPict).picFrame;
- OffsetRect(&rPic, -rPic.left, -rPic.top);
- OffsetRect(&rPic, (gIconBox.left + gIconBox.right - rPic.right)/2, (gIconBox.top + gIconBox.bottom - rPic.bottom)/2);
- DrawPicture(gSplashPict, &rPic);
- }
- /* gray the image if we're in the background */
- if ( ! (gPWActive && (theWindow == FrontWindow())) ) {
- GrayOutBox(&gIconBox);
- }
- /* restore previous colors */
- RGBForeColor(&sForground);
- RGBBackColor(&sBackground);
- }
-
-
-
- static Boolean VerifyPackage(FSSpec *target) {
- CInfoPBRec cat;
- OSErr err;
- long packageFolderDirID;
- Str255 name, errstr;
- FSSpec aliasFile, mainFile;
- Boolean targetIsFolder, wasAliased;
- long aliasCount;
-
- /* set up locals */
- aliasCount = 0;
-
- /* make sure file sharing is turned off */
- if ( FileSharingAppIsRunning() ) {
- GetIndString(errstr, kMainStringList, kFileSharingOn);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
-
- /* check the target's flags */
- memset(&cat, 0, sizeof(cat));
- cat.dirInfo.ioNamePtr = target->name;
- cat.dirInfo.ioVRefNum = target->vRefNum;
- cat.dirInfo.ioFDirIndex = 0;
- cat.dirInfo.ioDrDirID = target->parID;
- err = PBGetCatInfoSync(&cat);
- if (err != noErr) return false;
- if ((cat.dirInfo.ioFlAttrib & 16) == 0) {
- GetIndString(errstr, kMainStringList, kNotAFolder);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- /* if the bundle flag is set and we arrive here,
- then we didn't recognize the package in the first
- place. That's an internal error. */
- if ((cat.dirInfo.ioDrUsrWds.frFlags & kHasBundle) != 0) {
- GetIndString(errstr, kMainStringList, kBundleAlreadySet);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
-
- /* search for a top level alias file */
- packageFolderDirID = cat.dirInfo.ioDrDirID;
- memset(&cat, 0, sizeof(cat));
- cat.dirInfo.ioNamePtr = name;
- cat.dirInfo.ioVRefNum = target->vRefNum;
- cat.dirInfo.ioFDirIndex = 1;
- cat.dirInfo.ioDrDirID = packageFolderDirID;
- while (PBGetCatInfoSync(&cat) == noErr) {
- if (((cat.dirInfo.ioFlAttrib & 16) == 0) && ((cat.dirInfo.ioDrUsrWds.frFlags & kIsAlias) != 0)) {
- aliasCount += 1;
- /* resolve the alias file */
- err = FSMakeFSSpec(target->vRefNum, packageFolderDirID, name, &aliasFile);
- if (err != noErr) return false;
- mainFile = aliasFile;
- err = ResolveAliasFile(&mainFile, false, &targetIsFolder, &wasAliased);
- if (err != noErr) {
- GetIndString(errstr, kMainStringList, kBrokenAlias);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- if (targetIsFolder) {
- GetIndString(errstr, kMainStringList, kAliasRefersToFolder);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- }
- cat.dirInfo.ioFDirIndex++;
- cat.dirInfo.ioDrDirID = packageFolderDirID;
- }
- /* check the alias count */
- if (aliasCount == 0) {
- GetIndString(errstr, kMainStringList, kNoAliasPresent);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- if (aliasCount > 1) {
- GetIndString(errstr, kMainStringList, kMoreThanOneAlias);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- /* make sure the alias and the target are in separate directories */
- if ( mainFile.parID == aliasFile.parID ) {
- GetIndString(errstr, kMainStringList, kInSameDirectory);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- /* make sure the target is inside of the package directory */
- if ( ! FSSpecIsInDirectory(&mainFile, target->vRefNum, packageFolderDirID) ) {
- GetIndString(errstr, kMainStringList, kMainOutsideOfPackage);
- ParamAlert(kPackageDidNotVerify, target->name, errstr);
- return false;
- }
- /* all tests successful */
- return true;
- }
-
-
-
- static OSStatus FolderToPackage(FSSpec *packageDir) {
- CInfoPBRec cat;
- OSErr err;
- FSSpec aliasFile, mainFile;
- long packageFolderDirID;
- Boolean foundAlias, targetIsFolder, wasAliased;
- Str255 name;
- /* set up locals */
- foundAlias = false;
- /* find out the folder's directory ID */
- memset(&cat, 0, sizeof(cat));
- cat.dirInfo.ioNamePtr = packageDir->name;
- cat.dirInfo.ioVRefNum = packageDir->vRefNum;
- cat.dirInfo.ioFDirIndex = 0;
- cat.dirInfo.ioDrDirID = packageDir->parID;
- err = PBGetCatInfoSync(&cat);
- if (err != noErr) return err;
- packageFolderDirID = cat.dirInfo.ioDrDirID;
- /* search for a top level alias file */
- memset(&cat, 0, sizeof(cat));
- cat.dirInfo.ioNamePtr = name;
- cat.dirInfo.ioVRefNum = packageDir->vRefNum;
- cat.dirInfo.ioFDirIndex = 1;
- cat.dirInfo.ioDrDirID = packageFolderDirID;
- while (PBGetCatInfoSync(&cat) == noErr) {
- if (((cat.dirInfo.ioFlAttrib & 16) == 0) && ((cat.dirInfo.ioDrUsrWds.frFlags & kIsAlias) != 0)) {
- /* resolve the alias file */
- err = FSMakeFSSpec(packageDir->vRefNum, packageFolderDirID, name, &aliasFile);
- if (err != noErr) return err;
- mainFile = aliasFile;
- err = ResolveAliasFile(&mainFile, false, &targetIsFolder, &wasAliased);
- if (err != noErr) return err;
- foundAlias = true;
- break;
- }
- cat.dirInfo.ioFDirIndex++;
- cat.dirInfo.ioDrDirID = packageFolderDirID;
- }
- if ( ! foundAlias) return paramErr;
- /* update the alias file to a relative path */
- err = UpdateRelativeAliasFile(&aliasFile, &mainFile);
- if (err != noErr) return err;
- /* set the package flag */
- cat.dirInfo.ioNamePtr = packageDir->name;
- cat.dirInfo.ioVRefNum = packageDir->vRefNum;
- cat.dirInfo.ioFDirIndex = 0;
- cat.dirInfo.ioDrDirID = packageDir->parID;
- err = PBGetCatInfoSync(&cat);
- if (err != noErr) return err;
- cat.dirInfo.ioDrDirID = packageDir->parID;
- cat.dirInfo.ioDrUsrWds.frFlags |= kHasBundle;
- err = PBSetCatInfoSync(&cat);
- if (err != noErr) return err;
- return noErr;
- }
-
-
- static OSStatus PackageToFolder(FSSpec *target) {
- CInfoPBRec cat;
- OSErr err;
- cat.dirInfo.ioNamePtr = target->name;
- cat.dirInfo.ioVRefNum = target->vRefNum;
- cat.dirInfo.ioFDirIndex = 0;
- cat.dirInfo.ioDrDirID = target->parID;
- err = PBGetCatInfoSync(&cat);
- if (err != noErr) return err;
- cat.dirInfo.ioDrDirID = target->parID;
- cat.dirInfo.ioDrUsrWds.frFlags &= ~ kHasBundle;
- err = PBSetCatInfoSync(&cat);
- return err;
- }
-
-
-
-
-
- /* HitPackageWindow is called when the dialog manager's DialogSelect indicates
- that an item in the main finder drag pro window has been hit. Here,
- either we begin a drag, or we adjust the promise/regular hfs controls */
- void HitPackageWindow(DialogPtr theDialog, EventRecord *event, short itemNo) {
- switch (itemNo) {
- case kPackageUserItem:
- break;
-
- case kFolderItem: /* turn it into a folder */
- if (gFolderTypeSelection != kFolderIsFolder) {
- FSSpec target;
- Boolean wasChanged;
- if (ResolveAlias(NULL, gFileAlias, &target, &wasChanged) != noErr) {
- SetNewDisplay(NULL);
- } else {
- if (PackageToFolder(&target) == noErr) {
- SetNewDisplay(&target); /* update the view */
- ShowChangesInFinderWindow(target.vRefNum, target.parID);
- }
- }
- }
- break;
-
- case kPackageItem: /* turn it into a package */
- if (gFolderTypeSelection != kFolderIsPackage) {
- FSSpec target;
- Boolean wasChanged;
- if (ResolveAlias(NULL, gFileAlias, &target, &wasChanged) != noErr) {
- SetNewDisplay(NULL);
- } else {
- if (VerifyPackage(&target)) {
- OSStatus err;
- err = FolderToPackage(&target);
- if (err != noErr) {
- Str255 errStr;
- NumToString(err, errStr);
- ParamAlert(kFailedToCreatePackage, errStr, target.name);
- } else {
- SetNewDisplay(&target); /* update the view */
- ShowChangesInFinderWindow(target.vRefNum, target.parID);
- }
- }
- }
- }
- break;
- }
- }
-
-
-
- /* CreatePackageWindow creates the package window. If it cannot be
- created, then an error is returned. */
- OSStatus CreatePackageWindow(void) {
- OSErr err;
- Boolean installedTracker, installedReceiver;
- short itemt;
- Rect itemb;
- Handle itemh;
- DialogPtr dialog;
- long itemSize;
- Point where;
-
- /* set up locals for recovery */
- dialog = NULL;
- installedTracker = installedReceiver = false;
-
- /* get other resources */
- gSplashPict = GetPicture(kSpashPictResource);
- if (gSplashPict == NULL) { err = resNotFound; goto bail; }
- /* create the dialog */
- dialog = GetNewDialog(kPackageDialogResource, NULL, (WindowPtr) (-1));
- if (dialog == NULL) { err = memFullErr; goto bail; }
-
- /* grab and set up our dialog items */
- GetDialogItem(dialog, kPackageUserItem, &itemt, (Handle*) &itemh, &gIconBox);
- myUserItem = NewUserItemProc(PackageWindowUserItem);
- if (myUserItem == NULL) { err = memFullErr; goto bail; }
- SetDialogItem(dialog, kPackageUserItem, userItem, (Handle) myUserItem, &gIconBox);
- GetDialogItem(dialog, kFolderItem, &itemt, (Handle*) &gFolderButton, &itemb);
- GetDialogItem(dialog, kPackageItem, &itemt, (Handle*) &gPackageButton, &itemb);
-
- /* set initial control values */
- SetControlValue(gPackageButton, (gFolderTypeSelection == kFolderIsPackage ? 1 : 0));
- SetControlValue(gFolderButton, (gFolderTypeSelection == kFolderIsFolder ? 1 : 0));
- HiliteControl(gPackageButton, 255);
- HiliteControl(gFolderButton, 255);
-
- /* calculate the drawn icon's boundary */
- SetRect(&gIconImage, 0, 0, 32, 32);
- OffsetRect(&gIconImage, (gIconBox.right + gIconBox.left - 32) / 2, gIconBox.top + 32);
-
- /* install the drag handlers */
- gMainTrackingHandler = NewDragTrackingHandlerProc(MyDragTrackingHandler);
- if (gMainTrackingHandler == NULL) { err = memFullErr; goto bail; }
- err = InstallTrackingHandler(gMainTrackingHandler, dialog, NULL);
- if (err != noErr) { err = memFullErr; goto bail; }
- installedTracker = true;
-
- gMainReceiveHandler = NewDragReceiveHandlerProc(MyDragReceiveHandler);
- if (gMainReceiveHandler == NULL) { err = memFullErr; goto bail; }
- err = InstallReceiveHandler(gMainReceiveHandler, dialog, NULL);
- if (err != noErr) { err = memFullErr; goto bail; }
- installedReceiver = true;
-
- /* position the window, if necessary */
- if (GetCollectionItem(GetCollectedPreferences(), 'QDPt', 1, (itemSize = sizeof(where), &itemSize), &where) == noErr) {
- MoveWindow(dialog, where.h, where.v, true);
- }
- /* done, window complete */
- ShowWindow(dialog);
- gPackageWindow = dialog;
- return noErr;
-
- bail:
- if (installedReceiver)
- RemoveReceiveHandler(gMainReceiveHandler, dialog);
- if (installedTracker)
- RemoveTrackingHandler(gMainTrackingHandler, dialog);
- if (dialog != NULL) DisposeDialog(dialog);
- return err;
- }
-
- /* ClosePackageWindow closes the package window and disposes of
- any structures allocated when it was opened. */
- void ClosePackageWindow(void) {
- Point where;
- SetPort(gPackageWindow);
- where = * (Point*) &gPackageWindow->portRect;
- LocalToGlobal(&where);
- AddCollectionItem(GetCollectedPreferences(), 'QDPt', 1, sizeof(where), &where);
- SetNewDisplay(NULL);
- DisposeDialog(gPackageWindow);
- }
-
-